package com.interview.controller;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.interview.entity.AnswerSubmitRequest;
import com.interview.entity.QuesUser;
import com.interview.entity.User;
import com.interview.result.AnswerScoreResult;
import com.interview.result.Result;
import com.interview.result.ResultCode;
import com.interview.service.QuesUserService;
import com.interview.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import reactor.core.publisher.Flux;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Mono;

@Tag(name = "ChatController", description = "ChatController")
@RequiredArgsConstructor
@RestController
@RequestMapping("/ai")
public class ChatController {
    private static final Logger logger = LoggerFactory.getLogger(ChatController.class);
    @Autowired
    private VectorStore vectorStore;
    @Autowired
    private QuesUserService quesUserService;
    @Autowired
    private UserService userService;

    private final ChatClient chatClient;

    @Operation(summary = "chat")
    @GetMapping(value = "/chat", produces = "text/html;charset=UTF-8")
    public Flux<String> chat(@RequestParam("prompt") String prompt) {
        // 从向量库检索相关文档
        long startTime = System.currentTimeMillis();
        logger.info("Received chat request with prompt: {}", prompt);
        List<Document> documents = vectorStore.similaritySearch(
                SearchRequest.builder()
                        .query(prompt)
                        .topK(1)
                        .build()
        );

        // 构建提示模板
        String promptTemplate = """
                    你可以根据下面搜索到的内容回复用户
                    ### 用户的问题是
                    %s
                    ### 具体内容
                    %s
                """;
        /*if (prompt.contains("面试题")) {
            promptTemplate += """
                            如果是为用户输出面试题，请严格按以下格式反馈(要求纯文本，不用markdown的代码格式)：
                                格式示例：\s
                                {
                                "quesList":\s
                                [
                                {
                                "ques": "面试题目1",\s
                                "exampleAnswer": "示例答案1"
                                },
                                {
                                "ques": "面试题目2",\s
                                "exampleAnswer": "示例答案2"
                                },
                                ......
                                ]
                                }
                    根据用户要求的面试题数量依次格式增加面试题.
                    """;
        }*/

        // 填充提示内容
        String q = String.format(promptTemplate,
                prompt,
                documents.isEmpty() ? "无相关信息" : documents.get(0).getText()
        );
        AtomicBoolean thinkOver = new AtomicBoolean(false);
        long endTime = System.currentTimeMillis();
        logger.info("Chat request completed in {} ms", endTime - startTime);
        return chatClient
                .prompt(q)
                .stream()
                .content().timeout(Duration.ofSeconds(600))
                .mapNotNull(s -> {
                    if ("</think>".equals(s)) {
                        thinkOver.set(true);
                    }
                    return thinkOver.get() ? s : null;
                });
    }

    @Operation(summary = "生成面试题")
    @GetMapping("/generateInterview")
    public Result generateInterview(HttpSession session) throws JsonProcessingException {
        Integer userId = (Integer) session.getAttribute("userId");
        if (userId == null) {
            return new Result(401, "请求失败", "请先登录！");
        }

        User user = userService.userInfo(userId);

        String prompt = "该用户的求职意向为：" + user.getJobInterest() +
                "掌握技术栈为：" + user.getTechTack() +
                "请根据该用户的信息生成5道专属面试题" +
                "请严格按以下json格式反馈：\n" +
                "每个问题的示例答案必须在同一个双引号中并且双引号内不允许出现双引号,每一个exampleAnswer元素结尾不加','" +
                "{" +
                "\"quesList\":" +
                "[" +
                "{" +
                "\"ques\": \"面试题目1\"," +
                "\"exampleAnswer\": \"示例答案1\"" +
                "}," +
                "......" +
                "]" +
                "}";

        // 调用大模型API获取原始响应
        String rawResponse = chatClient.prompt(prompt).call().content();

        // 剔除<think></think>标签及其内容
        String jsonResponse = rawResponse.replaceAll("<think>[\\s\\S]*?</think>", "");
        // 剔除反引号
        jsonResponse = jsonResponse.replaceAll("`", "")
                .replaceAll("text", "")
                .replaceAll("json", "");
        System.out.println(jsonResponse);
        // 解析面试题JSON数据
        ObjectMapper mapper = new ObjectMapper();
        Map<String, List<Map<String, String>>> data = mapper.readValue(jsonResponse, Map.class);
        List<Map<String, String>> quesList = data.get("quesList");

        QuesUser quesUser = new QuesUser();
        quesUser.setUserId(userId);
        // 保存面试题到数据库
        if (quesList != null) {
            for (Map<String, String> item : quesList) {
                quesUser.setQuesDesc(item.get("ques"));
                quesUser.setExReply(item.get("exampleAnswer"));
                quesUserService.insertQuesUser(quesUser);
            }
        }
        return new Result(ResultCode.SUCCESS, "您的面试题已出炉，请回主页查收！");
    }

    @Operation(summary = "提交回答")
    @PostMapping("/submitAnswer/{quesUserId}")
    public Result submitAnswer(HttpSession session,
                               @PathVariable("quesUserId") Integer quesUserId,
                               @RequestBody AnswerSubmitRequest request) throws JsonProcessingException {
        Integer userId = (Integer) session.getAttribute("userId");
        if (userId == null) {
            return new Result(401, "请求失败", "请先登录！");
        }

        // 1. 参数校验
        if (StringUtils.isBlank(request.getUserReply())) {
            return new Result(ResultCode.FAILED, "回答不能为空");
        }

        QuesUser quesUser = quesUserService.quesUserInfo(quesUserId);

        String prompt = "面试题为：" + quesUser.getQuesDesc() +
                "，用户的回答为：" + request.getUserReply() +
                "请根据该用户的回答给用户打分并给出提升建议，" +
                "对用户答案的评判可以从回答的深度和回答的正确性以及回答的答案是否完整等角度给出评分（满分10分）和建议" +
                "请严格按以下json格式反馈：\n" +
                "{" +
                "\"suggest\": \"建议内容\"," +
                "\"score\": \"评分\"" +
                "}";
        // 调用大模型API获取原始响应
        String rawResponse = chatClient.prompt(prompt).call().content();

        // 剔除<think></think>标签及其内容
        String jsonResponse = rawResponse.replaceAll("<think>[\\s\\S]*?</think>", "");
        // 剔除反引号
        jsonResponse = jsonResponse.replaceAll("`", "")
                .replaceAll("text", "")
                .replaceAll("json", "");
        System.out.println(jsonResponse);

        // 解析JSON数据
        ObjectMapper mapper = new ObjectMapper();
        // 使用Map<String, Object>而不是Map<String, String>，因为score可能是数字
        Map<String, Object> data = mapper.readValue(jsonResponse, Map.class);

        // 直接获取建议
        String suggest = (String) data.get("suggest");

        // 获取分数，处理可能是Integer或String的情况
        Object scoreObj = data.get("score");
        Integer score;

        if (scoreObj instanceof Integer) {
            score = (Integer) scoreObj;
        } else if (scoreObj instanceof String) {
            score = Integer.parseInt((String) scoreObj);
        } else {
            throw new IllegalArgumentException("无法解析score字段: " + scoreObj);
        }

        // 更新问题状态
        quesUser.setUserReply(request.getUserReply());
        quesUser.setSuggestion(suggest);
        quesUser.setPoint(score);
        quesUser.setQuesStatus(1);
        quesUserService.updateQuesUser(quesUser);

        // 更新用户完成题目数
        // mapper接口未采用动态sql，待开发中

        return new Result(ResultCode.SUCCESS,"提交成功！");
    }


}